/* 
 * cms，一个基于J2EE架构内容管理系统
 * Copyright © GrayRabbit Co., Ltd. All rights reserved.
 * Department:运营department
 * 更多信息请访问：
 * http://code.google.com/p/gray-rabbit-cms/
 */
package org.grayrabbit.cms.service.system.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.grayrabbit.cms.constant.ConstantOperCode;
import org.grayrabbit.cms.constant.DBInitId;
import org.grayrabbit.cms.dao.site.SiteDao;
import org.grayrabbit.cms.dao.system.AdminDao;
import org.grayrabbit.cms.dao.system.AdminOperRelaDao;
import org.grayrabbit.cms.dao.system.RoleOperRelaDao;
import org.grayrabbit.cms.entity.Admin;
import org.grayrabbit.cms.entity.AdminOperRela;
import org.grayrabbit.cms.entity.OperLog;
import org.grayrabbit.cms.entity.Role;
import org.grayrabbit.cms.entity.RoleOperRela;
import org.grayrabbit.cms.entity.Site;
import org.grayrabbit.cms.service.system.AdminService;
import org.grayrabbit.cms.util.MD5;
import org.grayrabbit.cms.vo.system.AdminBean;
import org.grayrabbit.cms.vo.system.LoginInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import org.grayrabbit.dao.util.Page;
import org.grayrabbit.service.impl.GenericServiceImpl;
/**
 * <b>OperLog</b>的service实现类，事务加此处：





 * @version 1.0,创建时间: 2011-05-16 15:55:12  
 */
@Service
@Transactional
public class AdminServiceImpl extends GenericServiceImpl implements AdminService {
	private  static final Logger LOGGER = LoggerFactory.getLogger(AdminServiceImpl.class);
	/**
	 * 注入dao层：
	 */
	@Autowired
	@Qualifier("adminDaoImpl")
	private AdminDao adminDao;
 
	
	@Autowired
	@Qualifier("adminOperRelaDaoImpl")
	private AdminOperRelaDao adminOperRelaDao;
	
	@Autowired
	@Qualifier("roleOperRelaDaoImpl")
	private RoleOperRelaDao roleOperRelaDao;
	
	@Autowired
	@Qualifier("siteDaoImpl")
	private SiteDao siteDao;
	
	/**
	 * 此方法执行时为只读事务：
	 * @see AdminService#getOperLog(String)
	 */
	@Transactional(readOnly=true)
	public Admin getAdmin(final String adminId){
		Admin admin = adminDao.findById(adminId);
		adminDao.initialize(admin);
		adminDao.initialize(admin.getRole());
		return admin;
	}
	
	/**
	 * @see AdminService#delete(String)
	 */
	@Transactional
	public void delete(final Admin admin) {
		List<AdminOperRela> adminOperList=null;
		adminOperList=adminOperRelaDao.findAllAuthCodeByAdminId(admin.getAdminId());
		if(adminOperList!=null&&(adminOperList.size()>0)){
			for(AdminOperRela adminOper:adminOperList){
				adminOperRelaDao.makeTransient(adminOper);
			}
		}
		adminDao.makeTransient(admin);
		AdminContext.remove(admin.getLoginName());//清除用户缓存
	}
	
	/**
	 * 根据主键id列删除，批量删除OperLog
	 * @see AdminService#delete(String[])
	 */
	public void delete(final String[] key) {
		int i =0;
		for(String id : key){
			List<AdminOperRela> adminOperList=null;
			adminOperList=adminOperRelaDao.findAllAuthCodeByAdminId(id);
			if(adminOperList!=null&&(adminOperList.size()>0)){
				for(AdminOperRela adminOper:adminOperList){
					adminOperRelaDao.makeTransient(adminOper);
				}
			}
			Admin admin = adminDao.findById(id);
			adminDao.makeTransient(adminDao.findById(id));
			AdminContext.remove(admin.getLoginName());//清除用户缓存
			i++;
			if(i==MAX_CLEAR)
				adminDao.clear();
		}
	}
	
	
	/**
	 * @see AdminService#save(OperLog)
	 */
	@Transactional
	public void save(final Admin admin) {
		adminDao.makePersistent(admin);
		AdminContext.remove(admin.getLoginName());//清除用户缓存
	}
	
	/**
	 * 此方法执行时为只读事务：
	 * @see AdminService#getPage(AdminBean)
	 */
	@Transactional(readOnly=true)
	public Page<Admin> getPage(final AdminBean adminBean){
		Page<Admin> page =  new Page<Admin>();
		page.setTotal(adminDao.count(adminBean));
		page.setResult(adminDao.findByQc(adminDao.assembly(adminBean)));
		return page;
	}

	/**
	 * 此方法执行时为只读事务：
	 * @see AdminService#list(Page, AdminBean)
	 */
	public void list(Page<Admin> page, AdminBean adminBean) {
		if(page==null)
			return;
		if(page.isAutoCount()){
			page.setTotal(adminDao.count(adminBean));
		}
		List<Admin> admins=adminDao.findByPage(page,adminBean);
		if(admins!=null){
			for(Admin a:admins){
				adminDao.initialize(a.getRole());
			}
		}
		page.setResult(admins);
	}
	

	/**
	 * 登录名、密码查询admin
	 * 登陆验证身份
	 */ 
	public Admin getLoginAdmin(String loginName) {
		LOGGER.debug("DAO 开始查询 user:{}",loginName);
		Admin admin = adminDao.getLoginAdmin(loginName);
		LOGGER.debug("DAO 结束查询 user:{}",loginName);
		return admin ;
		 
	}
	
	public boolean checkNameUnique(AdminBean adminBean,String adminId){
		return adminDao.checkNameUnique(adminBean,adminId);
	}
	
	public List<Admin> getAdminsByOper(String operTargetId,String operTargetType,String operCode){
		return adminDao.getAdminsByOper(operTargetId,operTargetType, operCode);
	}
	
	/*
	 * 批量初始化密码
	 */
	public void initPwd(String[] keys,String passwd){
		if(keys!=null){
			for(String str:keys){
				Admin a=adminDao.findById(str);
				a.setPasswd(passwd);
				adminDao.makePersistent(a);
				AdminContext.remove(a.getLoginName());//清除用户缓存
			}
		}
	}
	
	/**
	 * 初始化密码
	 * @param key
	 */
	public void initPwd(String key,String passwd){
		if(StringUtils.isNotBlank(key)){
			String[] str=new String[1];
			str[0]=key;
			this.initPwd(str,passwd);
		}
	}
	
	public void disableOrEnable(String adminId){
		Admin a=adminDao.findById(adminId);
		if((a!=null)&&(a.getActiveStatus()!=null)&&(!a.getActiveStatus())){
			a.setActiveStatus(true);
		}else{
			a.setActiveStatus(false);
		}
		adminDao.makePersistent(a);
		AdminContext.remove(a.getLoginName());//清除用户缓存
	}
	
	/**
	 * 批量启用禁用管理员状态
	 */
	public void adminActiveStatus(String[] ids,boolean active){
		if(ids!=null){
			Admin a=null;
			for(String str:ids){
				a=adminDao.findById(str);
				a.setActiveStatus(active);
				adminDao.makePersistent(a);
				AdminContext.remove(a.getLoginName());//清除用户缓存
			}
		}
	}
	
	public List<Admin> getAllUsableAdmins(){
		return adminDao.getAllUsableAdmins();
	}

	public String getRealName(String loginName) {
		if(StringUtils.isNotBlank(loginName)){
			Admin admin = adminDao.getLoginAdmin(loginName);
			if(admin != null){			
				adminDao.initialize(admin);
				return admin.getRealName();
			}			
		}		
		return "";
	}
	
	public List<Admin>  AllAuditorAdmins(String AuditType,String targetId){
		if(StringUtils.isBlank(AuditType) || StringUtils.isBlank(targetId))
			return null;
		String codeId = null;
		if(ConstantOperCode.AUTH_CAT_TYPE.equals(AuditType)){
			codeId = ConstantOperCode.CAT_DOC_AUDIT_ID;
		}else if(ConstantOperCode.AUTH_TOPIC_TYPE.equals(AuditType)){
			codeId = ConstantOperCode.TOPIC_DOC_AUDIT_ID;
		}else{
			return null;
		}		
		List<Admin> adminIds = adminOperRelaDao.findCategoryAuditorsAdmin(codeId, targetId);
		List<Role> roleIds = roleOperRelaDao.findCategoryAuditorsRole(codeId, targetId);
		List<Admin>  list = new ArrayList<Admin>();
		for(Admin admin : adminIds){
			try {
				if(admin.getActiveStatus() == null  || admin.getActiveStatus()){
					list.add(admin);
				}				
			} catch (Exception e) {
				LOGGER.error("id 为：{} 的管理员不存在", admin.getAdminId());
			}
		}
		for(Role role: roleIds){
			try {
				if(!role.getActiveStatus()){
					continue;
				}else{
					List<Admin> list_r = adminDao.findUsableAdminByRoleId(role.getRoleId());
					list.addAll(list_r);
				} 
			} catch (Exception e) {
				LOGGER.error("id 为：{} 的角色管理员查询异常", role.getRoleId());
			}
		}
		return list;
	}

	@Transactional
	public LoginInfo logon(String loginName, String passwd) {
		LOGGER.debug("start user:{}",loginName);
		long ls = System.currentTimeMillis();
		LoginInfo loginInfo = new LoginInfo();
		if(AdminContext.get(loginName)==null){
			Admin admin = this.getLoginAdmin(loginName);
			if(admin==null){
				loginInfo.setLoginState(LoginInfo.LoginState.notexist);
			}else{
				if(StringUtils.isBlank(passwd)
						|| !MD5.getMD5Str(passwd).equalsIgnoreCase(admin.getPasswd())){
					loginInfo.setLoginState(LoginInfo.LoginState.wrongpassword);
				}else if(admin.getActiveStatus()==null || admin.getActiveStatus().booleanValue()==false){
					loginInfo.setLoginState(LoginInfo.LoginState.disabled);
				}else{
					long s = System.currentTimeMillis();
					loadAuthCode(admin);
					LOGGER.debug("加载权限 user:{},耗时:{}",loginName,System.currentTimeMillis()-s);
					s = System.currentTimeMillis();
					if(!DBInitId.CMS_SUPPER_ADMIN_ID.equals(admin.getAdminId()))
						AdminContext.put(admin);
					LOGGER.debug("存入缓存 catch:{},耗时:{}",loginName,System.currentTimeMillis()-s);
					loginInfo.setAdmin(admin);
					loginInfo.setLoginState(LoginInfo.LoginState.success);
				}
			}
		}else{//从缓存中取数据
			LOGGER.debug("================={}===============================",loginName);
			long s = System.currentTimeMillis();
			loginInfo.setAdmin(AdminContext.get(loginName));
			if(StringUtils.isBlank(passwd)
					|| !MD5.getMD5Str(passwd).equalsIgnoreCase(AdminContext.get(loginName).getPasswd())){
				loginInfo.setLoginState(LoginInfo.LoginState.wrongpassword);
			}else{
				loginInfo.setLoginState(LoginInfo.LoginState.success);
			}
			LOGGER.debug("获取缓存 信息:{},耗时:{}",loginName,System.currentTimeMillis()-s);
		}
		LOGGER.debug("end user:{},总耗时:{}",loginName,System.currentTimeMillis()-ls);
		return loginInfo;
	}
	
	private void  loadAuthCode(Admin admin){
		Set<String> set = new HashSet<String>();
		List<Site> currentSites = null;
		if(DBInitId.CMS_SUPPER_ADMIN_ID.equals(admin.getAdminId())){
			currentSites = siteDao.findAllUsableSite();
		}else{
			if(StringUtils.isNotBlank(admin.getAdminId()) 
					&& (admin.getActiveStatus() != null 
							&&  admin.getActiveStatus().booleanValue())){
					currentSites = loadAdminAuthCode(admin.getAdminId(),set);
			}
			if(admin.getRole() != null 
					&& admin.getRole().getActiveStatus()!=null
					&& admin.getRole().getActiveStatus().booleanValue()){
				List<Site> curSites = loadRoleAuthCode(admin.getRole().getRoleId(),set);
				if(currentSites==null){
					currentSites = curSites;
				}else{
					for (Site site : curSites) {
						if(!currentSites.contains(site)){
							currentSites.add(site);
						}
					}
				}
			}
		}
		admin.setPerssmins(set);
		admin.setAuthSites(currentSites);
	}
	
	
	private List<Site> loadAdminAuthCode(String adminId, Set<String> set) {
		List<Site> sites = new ArrayList<Site>();
		long start = System.currentTimeMillis();
		List<AdminOperRela> list = adminOperRelaDao.findAllAuthCodeByAdminId(adminId);
		LOGGER.debug("end findAllAuthCodeByAdminId耗时:{}",System.currentTimeMillis()-start);
		for(AdminOperRela r : list){
			StringBuilder sb = new StringBuilder();
			if(StringUtils.isNotBlank(r.getOperTargetId())){	
				sb.append(r.getOperTargetId());
			}
			if(StringUtils.isNotBlank(r.getOperTargetId2())){				
				sb.append("-");
				sb.append(r.getOperTargetId2());
			}
			if(StringUtils.isNotBlank(r.getOperTargetId3())){				
				sb.append("-");
				sb.append(r.getOperTargetId3());
			}
			if(StringUtils.isNotBlank(r.getOperTargetId4())){				
				sb.append("-");
				sb.append(r.getOperTargetId4());
			}
			if(StringUtils.isNotBlank(r.getOperTargetId5())){				
				sb.append("-");
				sb.append(r.getOperTargetId5());
			}
			String[] targetIds = sb.toString().split("-");
			String ids = sb.toString().replaceAll("-", "','");
			ids="'"+ids+"'";
			for(String s : targetIds){
				set.add(r.getOperCode().getOperCode()+"-"+s);
			}
			start = System.currentTimeMillis();
			List<Site> siteList = siteDao.findByTypeAndId(r.getOperCode().getOperCode(), ids);
			LOGGER.debug("end findAllAuthCodeByAdminId耗时:{}",System.currentTimeMillis()-start);
			if(siteList==null)//如果查询结果为空时，继续循环下一个类型
				continue;
			for(Site site : siteList){
				if(!sites.contains(site)){
					sites.add(site);
				}
			}
		} 
		return sites;
	}
	
	private List<Site> loadRoleAuthCode(String roleId, Set<String> set) {
		List<Site> sites = new ArrayList<Site>();
		long start = System.currentTimeMillis();
		List<RoleOperRela> list = roleOperRelaDao.findAllAuthCodeByRoleId(roleId);
		LOGGER.debug("end findAllAuthCodeByRoleId耗时:{}",System.currentTimeMillis()-start);
		for(RoleOperRela r : list){
			StringBuilder sb = new StringBuilder();
			if(StringUtils.isNotBlank(r.getOperTargetId())){	
				sb.append(r.getOperTargetId());
			}
			if(StringUtils.isNotBlank(r.getOperTargetId2())){				
				sb.append("-");
				sb.append(r.getOperTargetId2());
			}
			if(StringUtils.isNotBlank(r.getOperTargetId3())){				
				sb.append("-");
				sb.append(r.getOperTargetId3());
			}
			if(StringUtils.isNotBlank(r.getOperTargetId4())){				
				sb.append("-");
				sb.append(r.getOperTargetId4());
			}
			if(StringUtils.isNotBlank(r.getOperTargetId5())){				
				sb.append("-");
				sb.append(r.getOperTargetId5());
			}
			String[] targetIds = sb.toString().split("-");
			String ids = sb.toString().replaceAll("-", "','");
			ids="'"+ids+"'";
			for(String s : targetIds){
				set.add(r.getOperCode().getOperCode()+"-"+s);
			}
			start = System.currentTimeMillis();
			List<Site> siteList = siteDao.findByTypeAndId(r.getOperCode().getOperCode(), ids);
			LOGGER.debug("end findByTypeAndId耗时:{}",System.currentTimeMillis()-start);
			if(siteList==null)//如果查询结果为空时，继续循环下一个类型
				continue;
			for(Site site : siteList){
				if(!sites.contains(site)){
					sites.add(site);
				}
			}
			
		} 
		return sites;
	}
	@Transactional
	public void updateAdminSelf(Admin admin){
		Admin a =adminDao.findById(admin.getAdminId());
		a.setRealName(admin.getRealName());
		a.setNickName(admin.getNickName());
		a.setMobile(admin.getMobile());
		a.setTelephone(admin.getTelephone());
		a.setEmail(admin.getEmail());
		adminDao.makePersistent(a);
		AdminContext.remove(a.getLoginName());//清除用户缓存
	}
}